package com.ruoyi.job.service;


import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.business.domain.FreightInfo;
import com.ruoyi.business.domain.OrderInfo;
import com.ruoyi.business.mapper.FreightInfoMapper;
import com.ruoyi.business.mapper.OrderInfoMapper;
import com.ruoyi.common.constant.PushTemplate;
import com.ruoyi.common.core.domain.event.WarningEvent;
import com.ruoyi.common.enums.FreightStatus;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.common.enums.PushRefType;
import com.ruoyi.common.enums.SysYesNo;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * 推送任务处理
 */
@Slf4j
@Service
public class PushJobHandler {


    /**
     * 用户订单一直未分配车,推送给客服和调度和总经理(责任链)
     */
    @XxlJob("pushUnallocatedCar")
    public void pushUnallocatedCar() {
        XxlJobHelper.log("用户订单一直未分配车,推送给客服和调度和总经理(责任链)");
        OrderInfoMapper orderInfoMapper = SpringUtils.getBean(OrderInfoMapper.class);
        //     获得所有未分配车的订单
        // 两小时前
        DateTime offset = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -2);

        Long count = orderInfoMapper.selectCount(new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getOrderStatus, OrderStatus.INITIALIZED.getCode())
            .le(OrderInfo::getCreateTime, offset));
        XxlJobHelper.log("未分配车的订单数:{}", count);
        if (count == 0) {
            return;
        }
        // 推送给配置表中人员
        SpringUtils.context().publishEvent(WarningEvent.builder()
            .ownerId(IdUtil.getSnowflakeNextId())
            .ownerType("order")
            .type(PushRefType.DISPATCH_TRANSPORT_VEHICLE.getValue())
            .content(PushTemplate.DISPATCH_TRANSPORT_VEHICLE(count.intValue()))
            .build()
        );
    }

    /**
     * 回单一直没有上传,推送司机和调度和客服（并行）
     */
    @XxlJob("pushReceiptNotUploaded")
    public void pushReceiptNotUploaded() {
        XxlJobHelper.log("回单一直没有上传,推送司机和调度和客服（并行）");
        FreightInfoMapper freightInfoMapper = SpringUtils.getBean(FreightInfoMapper.class);
        //     获得所有未上传回单的运单
        // 两小时前
        DateTime offset = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -2);
        Long count = freightInfoMapper.selectCount(new LambdaQueryWrapper<FreightInfo>()
            .eq(FreightInfo::getFreightStatus, FreightStatus.WAITING_FOR_RECEIPT.getCode())
            .le(FreightInfo::getCreateTime, offset));
        XxlJobHelper.log("未上传回单的运单数:{}", count);
        if (count == 0) {
            return;
        }
        // 推送给配置表中人员
        SpringUtils.context().publishEvent(WarningEvent.builder()
            .ownerId(IdUtil.getSnowflakeNextId())
            .ownerType("freight")
            .type(PushRefType.UPLOAD_RECEIPT.getValue())
            .content(PushTemplate.UPLOAD_RECEIPT(count.intValue()))
            .build()
        );
    }

    /**
     * 订单打款凭证一直未上传,推送给财务和客服（并行）（定时）
     */
    @XxlJob("pushOrderPaymentVoucherNotUploaded")
    public void pushOrderPaymentVoucherNotUploaded() {
        XxlJobHelper.log("订单打款凭证一直未上传,推送给财务和客服（并行）（定时）");
        OrderInfoMapper orderInfoMapper = SpringUtils.getBean(OrderInfoMapper.class);
        //     获得所有未分配车的订单
        // 两小时前
        DateTime offset = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -2);

        Long count = orderInfoMapper.selectCount(new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getOrderStatus, OrderStatus.WAITING_FOR_PAYMENT.getCode())
            .le(OrderInfo::getCreateTime, offset));
        XxlJobHelper.log("未上传打款凭证的订单数:{}", count);
        if (count == 0) {
            return;
        }
        // 推送给配置表中人员
        SpringUtils.context().publishEvent(WarningEvent.builder()
            .ownerId(IdUtil.getSnowflakeNextId())
            .ownerType("order")
            .type(PushRefType.ORDER_PAYMENT_VOUCHER.getValue())
            .content(PushTemplate.ORDER_PAYMENT_VOUCHER(count.intValue()))
            .build()
        );
    }

    /**
     * 运单打款凭证一直未上传,推送给财务和客服（并行）（定时）
     */
    @XxlJob("pushFreightPaymentVoucherNotUploaded")
    public void pushFreightPaymentVoucherNotUploaded() {
        XxlJobHelper.log("运单打款凭证一直未上传,推送给财务和客服（并行）（定时）");
        FreightInfoMapper freightInfoMapper = SpringUtils.getBean(FreightInfoMapper.class);
        //     获得所有未上传回单的运单
        // 两小时前
        DateTime offset = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -2);
        Long count = freightInfoMapper.selectCount(new LambdaQueryWrapper<FreightInfo>()
            .eq(FreightInfo::getFreightStatus, FreightStatus.WAITING_FOR_PAYMENT.getCode())
            .le(FreightInfo::getCreateTime, offset));
        XxlJobHelper.log("未上传打款凭证的运单数:{}", count);
        if (count == 0) {
            return;
        }
        // 推送给配置表中人员
        SpringUtils.context().publishEvent(WarningEvent.builder()
            .ownerId(IdUtil.getSnowflakeNextId())
            .ownerType("freight")
            .type(PushRefType.WAYBILL_PAYMENT_VOUCHER.getValue())
            .content(PushTemplate.WAYBILL_PAYMENT_VOUCHER(count.intValue()))
            .build()
        );
    }

    /**
     * 紧急单挂起未被处理，推送给客服和调度和总经理（并行）（定时）
     */
    @XxlJob("pushUrgentOrderSuspended")
    public void pushUrgentOrderSuspended() {
        XxlJobHelper.log("紧急单挂起未被处理，推送给客服和调度和总经理（并行）（定时）");
        FreightInfoMapper freightInfoMapper = SpringUtils.getBean(FreightInfoMapper.class);
        //     获得所有未上传回单的运单
        // 两小时前
        DateTime offset = DateUtil.offset(new Date(), DateField.HOUR_OF_DAY, -2);
        List<FreightInfo> freightInfoList = freightInfoMapper.selectList(new LambdaQueryWrapper<FreightInfo>()
            .eq(FreightInfo::getIsUrgency, SysYesNo.Y.name())
            .le(FreightInfo::getCreateTime, offset));
        XxlJobHelper.log("未处理的紧急单数:{}", freightInfoList.size());
        if (freightInfoList.isEmpty()) {
            return;
        }
        // 推送给配置表中人员
        for (FreightInfo freightInfo : freightInfoList) {
            SpringUtils.context().publishEvent(WarningEvent.builder()
                .ownerId(freightInfo.getFreightId())
                .ownerType("freight")
                .type(PushRefType.URGENT_WAYBILL_SUSPENDED.getValue())
                .content(PushTemplate.URGENT_ORDER_SUSPENDED(freightInfo.getOrderNo()))
                .build()
            );
        }
    }
}
